#include "UpdateCommand.h"

//@author A0105475H

UpdateCommand::UpdateCommand(string inputSentence)
{
	storage=Storage::getInstance();
	parser(inputSentence);
}

UpdateCommand::~UpdateCommand(void)
{
}

string UpdateCommand::Execute()
{
	return storage->updateTask(index, newTask);
}

string UpdateCommand::Unexecute()
{
	storage->updateTask(index,previousTask);
	return CommonConstant::MESSAGE_UPDATE_UNDO_SUCCESSFULLY;
}

UpdateCommand::taskType UpdateCommand::determineTaskType(FloatingTask* task)
{
	char taskTypeChar = task->getTaskType();
	if(taskTypeChar == CommonConstant::TASK_TYPE_FLOATING)
		return UpdateCommand::floatingTask;
	else if(taskTypeChar == CommonConstant::TASK_TYPE_DEADLINE)
		return UpdateCommand::deadlineTask;
	else
	{
		assert(taskTypeChar == CommonConstant::TASK_TYPE_TIMED);
		return UpdateCommand::timedTask;
	}
}

Storage::updateType UpdateCommand::determineAttributeType(string attributeString)
{
	if(attributeString == CommonConstant::KEYWORD_TASK_TITLE)
		return Storage::updateType::UPDATE_TITLE;
	else if(attributeString == CommonConstant::KEYWORD_TASK_DESCRIPTION)
		return Storage::updateType::UPDATE_DESCRIPTION;
	else if(attributeString == CommonConstant::KEYWORD_TASK_LOCATION)
		return Storage::updateType::UPDATE_LOCATION;
	else if(attributeString == CommonConstant::KEYWORD_TASK_PERSON)
		return Storage::updateType::UPDATE_PERSON;
	else if(attributeString == CommonConstant::KEYWORD_TASK_PRIORITY)
		return Storage::updateType::UPDATE_PRIORITY;
	else if(attributeString == CommonConstant::KEYWORD_TASK_FINISHED_STATUS)
		return Storage::updateType::UPDATE_STATUS;
	else if(attributeString == CommonConstant::KEYWORD_TASK_START_TIME)
		return Storage::updateType::UPDATE_START_TIME;
	else if(attributeString == CommonConstant::KEYWORD_TASK_END_TIME)
		return Storage::updateType::UPDATE_END_TIME;
	else if(attributeString == CommonConstant::KEYWORD_TASK_START_DATE)
		return Storage::updateType::UPDATE_START_DATE;
	else if(attributeString == CommonConstant::KEYWORD_TASK_END_DATE)
		return Storage::updateType::UPDATE_END_DATE;
	else
		throw CommonConstant::MESSAGE_INVALID_FORMAT;
}

bool UpdateCommand::isValidStringPriority(string priorityString)
{
	std::transform(priorityString.begin(), priorityString.end(),priorityString.begin(), ::toupper);

	return (priorityString == CommonConstant::TASK_STRING_PRIORITY_HIGH ||
			priorityString == CommonConstant::TASK_STRING_PRIORITY_MEDIUM ||
			priorityString == CommonConstant::TASK_STRING_PRIORITY_LOW);
}

bool UpdateCommand::isValidIntPriority(string priorityString)
{
	if(isValidNumber(priorityString))
	{
		int priorityInt = stoi(priorityString,nullptr,CommonConstant::STOI_BASE);
		return (priorityInt == CommonConstant::TASK_INT_PRIORITY_HIGH || 
				priorityInt == CommonConstant::TASK_INT_PRIORITY_LOW ||
				priorityInt == CommonConstant::TASK_INT_PRIORITY_MEDIUM);
	}
	else 
		return false;
}

bool UpdateCommand::isValidStringStatus(string statusString)
{
	std::transform(statusString.begin(), statusString.end(),statusString.begin(), ::toupper);

	return (statusString == CommonConstant::TASK_STRING_STATUS_FINISHED ||
		statusString == CommonConstant::TASK_STRING_STATUS_NOT_FINISHED);
}

bool UpdateCommand::isValidIntStatus(string statusString)
{
	if(isValidNumber(statusString))
	{
		int statusInt = stoi(statusString,nullptr,CommonConstant::STOI_BASE);
		return (statusInt == CommonConstant::TASK_INT_STATUS_FINISHED || 
				statusInt == CommonConstant::TASK_INT_STATUS_NOT_FINISHED);
	}
	else 
		return false;
}

bool UpdateCommand::normalizeAndValidate(int day, int month, int year)
{
		struct tm t = {CommonConstant::TM_INITIALIZATION};
        t.tm_mday = day;
        t.tm_mon = month - CommonConstant::TM_MONTH_REFERENCE;
        t.tm_year = year - CommonConstant::TM_YEAR_REFERENCE;
        t.tm_isdst = CommonConstant::TM_SUMMER_TIME_OFF;

        time_t when = mktime(&t);
        struct tm norm;
		localtime_s(&norm,&when);

       if (norm.tm_mday == day    &&
           norm.tm_mon  == month - CommonConstant::TM_MONTH_REFERENCE &&
           norm.tm_year == year - CommonConstant::TM_YEAR_REFERENCE)
		   return true;
	   else
		   return false;
}

bool UpdateCommand::isValidDateFormat2(string dateString)
{
	int day, year, month;
	char* monthString = new char[CommonConstant::MONTH_STRING_MAX_LENGTH];

	if(sscanf(dateString.c_str(), "%s %2d %4d", monthString, &day, &year))
	{
		if(!setMonth(monthString,month))
			return false;
		if(!normalizeAndValidate(day,month,year))
			return false;
		return true;
    }
	else
		return false;
}

bool UpdateCommand::isValidTimeFormat1(string timeString)
{
	int hour, minute;
	if(timeString.length() > CommonConstant::MAX_LENGTH_TIME_FORMAT_1)
		return false;
	if (sscanf(timeString.c_str(), "%2d%2d",&hour,&minute))
	{
		if(hour > CommonConstant::MAX_HOUR || hour < CommonConstant::MIN_HOUR)
			return false;
		if(minute > CommonConstant::MAX_MINUTE || minute < CommonConstant::MIN_MINUTE)
			return false;
		return true;
	}
	return false;
}

bool UpdateCommand::isValidTimeFormat2(string timeString)
{
	int hour, minute;
	char* amOrpm = new char[CommonConstant::AMORPM_STRING_MAX_LENGTH];
	if(timeString.length() > CommonConstant::MAX_LENGTH_TIME_FORMAT_2)
		return false;
	if (sscanf(timeString.c_str(), "%d:%2d%s",&hour,&minute,amOrpm))
	{
		if(minute > CommonConstant::MAX_MINUTE || minute < CommonConstant::MIN_MINUTE)
			return false;

		for (unsigned int i = 0; i < strlen(amOrpm); ++i)
			amOrpm[i] = tolower(amOrpm[i]);
		
		if(!strcmp(amOrpm,CommonConstant::TIME_AM_CHAR))
		{
			if(hour > CommonConstant::MAX_HOUR_AM || hour < CommonConstant::MIN_HOUR_AM)
				return false;
		}
		else if(!strcmp(amOrpm,CommonConstant::TIME_PM_CHAR))
		{
			if(hour > CommonConstant::MAX_HOUR_PM || hour < CommonConstant::MIN_HOUR_PM)
				return false;
		}
		else
		{
			return false;
		}
		return true;
	}
	return false;
}

bool UpdateCommand::isValidDate(string dateString)
{
	if (isValidDateFormat1(dateString) || isValidDateFormat2(dateString))
		return true;
	else
		return false;
}

bool UpdateCommand::isValidTime(string timeString)
{
	if (isValidTimeFormat2(timeString) || isValidTimeFormat1(timeString))
		return true;
	else
		return false;
}

bool UpdateCommand::isLaterThan(time_t endTime, time_t startTime)
{
	if(difftime(endTime, startTime) <= 0)
		return false;
	else
		return true;
}

bool UpdateCommand::setMonth(char* monthString, int& month)
{
	for (unsigned int i = 0; i < strlen(monthString); i++)
		monthString[i] = tolower(monthString[i]);

	if (!strcmp(monthString,CommonConstant::MONTH_JAN_SHORT_CHAR) || !strcmp(monthString, CommonConstant::MONTH_JAN_LONG_CHAR)) 
		{
			month = CommonConstant::MONTH_JAN;
		}
        else if (!strcmp(monthString,CommonConstant::MONTH_FEB_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_FEB_LONG_CHAR))
		{
			month = CommonConstant::MONTH_FEB;
		}
        else if (!strcmp(monthString,CommonConstant::MONTH_MAR_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_MAR_LONG_CHAR))
		{
			month = CommonConstant::MONTH_MAR;
		}
		else if (!strcmp(monthString,CommonConstant::MONTH_APR_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_APR_LONG_CHAR))
		{
			month = CommonConstant::MONTH_APR;
		}
		else if (!strcmp(monthString,CommonConstant::MONTH_MAY_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_MAY_LONG_CHAR))
		{
			month = CommonConstant::MONTH_MAY;
		}
		else if (!strcmp(monthString,CommonConstant::MONTH_JUN_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_JUN_LONG_CHAR))
		{
			month = CommonConstant::MONTH_JUN;
		}
		else if (!strcmp(monthString,CommonConstant::MONTH_JUL_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_JUL_LONG_CHAR))
		{
			month = CommonConstant::MONTH_JUL;
		}
		else if (!strcmp(monthString,CommonConstant::MONTH_AUG_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_AUG_LONG_CHAR))
		{
			month = CommonConstant::MONTH_AUG;
		}
		else if (!strcmp(monthString,CommonConstant::MONTH_SEP_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_SEP_LONG_CHAR))
		{
			month = CommonConstant::MONTH_SEP;
		}
		else if (!strcmp(monthString,CommonConstant::MONTH_OCT_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_OCT_LONG_CHAR))
		{
			month = CommonConstant::MONTH_OCT;
		}
		else if (!strcmp(monthString,CommonConstant::MONTH_NOV_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_NOV_LONG_CHAR))
		{
			month = CommonConstant::MONTH_NOV;
		}
		else if (!strcmp(monthString,CommonConstant::MONTH_DEC_SHORT_CHAR) || !strcmp(monthString,CommonConstant::MONTH_DEC_LONG_CHAR))
		{
			month = CommonConstant::MONTH_DEC;
		}
		else
			return false;
		return true;
}

time_t UpdateCommand::parseTime(time_t previousTime, string inputSentence)
{
	struct tm tm;
	localtime_s(&tm,&previousTime);
	int hour, minute;
	char* amOrpm = new char[CommonConstant::AMORPM_STRING_MAX_LENGTH];
	if(isValidTimeFormat2(inputSentence))
	{
		sscanf(inputSentence.c_str(), "%d:%2d%s",&hour,&minute,amOrpm);
		
		for (unsigned int i = 0; i < strlen(amOrpm); ++i)
			amOrpm[i] = tolower(amOrpm[i]);

		if(!strcmp(amOrpm, CommonConstant::TIME_PM_CHAR))
		{
			if(hour < CommonConstant::NOON)
				hour += CommonConstant::AM_PM_CONVERTION;
		}
	}
	else
	{
		assert(isValidTimeFormat1(inputSentence) == true);
		sscanf(inputSentence.c_str(), "%2d%2d",&hour,&minute);
	}
	tm.tm_min=minute;
	tm.tm_hour=hour;

	return mktime(&tm);
}

time_t UpdateCommand::parseDate(time_t previousDate, string inputSentence)
{
	struct tm tm;
	localtime_s(&tm,&previousDate);
	int day, month, year;
	char* monthString= new char[CommonConstant::MONTH_STRING_MAX_LENGTH]; 

	if(isValidDateFormat1(inputSentence))
	{
		sscanf(inputSentence.c_str(), "%2d/%2d/%4d",&day,&month,&year);
	}
	else
	{
		assert(isValidDateFormat2(inputSentence) == true);
		sscanf(inputSentence.c_str(), "%s %2d %4d", monthString, &day, &year);
		setMonth(monthString,month);
	}
	
	tm.tm_mday = day;
	tm.tm_mon = month - CommonConstant::TM_MONTH_REFERENCE;
	tm.tm_year = year - CommonConstant::TM_YEAR_REFERENCE;

	return mktime(&tm);
}

void UpdateCommand::initializePreviousNewTask()
{
	previousTask=storage->retrieveTask(index);
	assert(previousTask != NULL);
	newTask = previousTask->clone();
}

void UpdateCommand::updateTitle(string titleString)
{
	newTask->setTitle(titleString);
}

void UpdateCommand::updateLocation(string locationString)
{
	newTask->setLocation(locationString);
}

void UpdateCommand::updateDescription(string descriptionString)
{
	newTask->setDescription(descriptionString);
}

void UpdateCommand::updatePerson(string personString)
{
	newTask->setPerson(personString);
}

void UpdateCommand::updatePriority(int priorityInt)
{
	newTask->setPriority(priorityInt);
}

void UpdateCommand::updatePriority(string priorityString)
{
	newTask->setPriority(priorityString);
}

void UpdateCommand::updateStatus(int statusInt)
{
	newTask->setFinishedStatus(statusInt);
}

void UpdateCommand::updateStatus(string statusString)
{
	newTask->setFinishedStatus(statusString);
}

void UpdateCommand::updateFloatingStartTime(string timeString)
{
		DeadlineTask* temp;
		temp = new DeadlineTask(previousTask);
		newTask = new TimedTask(temp);
				
		time_t previousStartTime=temp->getTimeAndDate();
		time_t newStartTime = parseTime(previousStartTime, timeString);
		time_t newEndTime= newStartTime + CommonConstant::SECONDS_PER_HOUR;

		newTask->setStartTimeAndDate(newStartTime);
		newTask->setEndTimeAndDate(newEndTime);
}

void UpdateCommand::updateDeadlineStartTime(string timeString)
{
	DeadlineTask* temp;
	temp = dynamic_cast<DeadlineTask*>(previousTask);
	newTask = new TimedTask(temp);
				
	time_t previousStartTime=newTask->getStartTimeAndDate();
	time_t previousEndTime=previousTask->getTimeAndDate();
	time_t newStartTime = parseTime(previousStartTime, timeString);

	if(!isLaterThan(previousEndTime, newStartTime))
		throw CommonConstant::MESSAGE_INVALID_START_TIME;

	newTask->setStartTimeAndDate(newStartTime);
	newTask->setEndTimeAndDate(previousEndTime);
}

void UpdateCommand::updateTimedStartTime(string timeString)
{
	time_t previousStartTime=previousTask->getStartTimeAndDate();
	time_t previousEndTime=previousTask->getEndTimeAndDate();
	time_t newStartTime = parseTime(previousStartTime, timeString);
	
	if(!isLaterThan(previousEndTime, newStartTime))
		throw CommonConstant::MESSAGE_INVALID_START_TIME;

	newTask->setStartTimeAndDate(newStartTime);
}

void UpdateCommand::updateFloatingEndTime(string timeString)
{
	DeadlineTask* temp;
	temp = new DeadlineTask(previousTask);
	newTask= temp;

	time_t previousEndTime=previousTask->getTimeAndDate();
	time_t newEndTime = parseTime(previousEndTime, timeString);
				
	newTask->setTimeAndDate(newEndTime);
}

void UpdateCommand::updateDeadlineEndTime(string timeString)
{
	time_t previousEndTime=previousTask->getTimeAndDate();
	time_t newEndTime = parseTime(previousEndTime, timeString);

	newTask->setTimeAndDate(newEndTime);
}

void UpdateCommand::updateTimedEndTime(string timeString)
{
	time_t previousStartTime=previousTask->getStartTimeAndDate();
	time_t previousEndTime=previousTask->getEndTimeAndDate();
	time_t newEndTime = parseTime(previousEndTime, timeString);
				
	if(!isLaterThan(newEndTime,previousStartTime))
		throw CommonConstant::MESSAGE_INVALID_END_TIME;

	newTask->setEndTimeAndDate(newEndTime);
}

void UpdateCommand::updateFloatingStartDate(string dateString)
{
	DeadlineTask* temp;
	temp = new DeadlineTask(previousTask);
	newTask = new TimedTask(temp);
				
	time_t previousStartTime=temp->getTimeAndDate();
	time_t newStartTime = parseDate(previousStartTime, dateString);
	time_t newEndTime= newStartTime + CommonConstant::MAX_SECONDS_DAY - 1;

	newTask->setStartTimeAndDate(newStartTime);
	newTask->setEndTimeAndDate(newEndTime);	
}

void UpdateCommand::updateDeadlineStartDate(string dateString)
{
	DeadlineTask* temp;
	temp = dynamic_cast<DeadlineTask*>(previousTask);
	newTask = new TimedTask(temp);

	time_t previousStartTime=newTask->getStartTimeAndDate();
	time_t previousEndTime=previousTask->getTimeAndDate();
	time_t newStartTime = parseDate(previousStartTime, dateString);
	
	if(!isLaterThan(previousEndTime, newStartTime))
		throw CommonConstant::MESSAGE_INVALID_START_TIME;

	newTask->setStartTimeAndDate(newStartTime);
	newTask->setEndTimeAndDate(previousEndTime);
}

void UpdateCommand::updateTimedStartDate(string dateString)
{
	time_t previousStartTime=previousTask->getStartTimeAndDate();
	time_t previousEndTime=previousTask->getEndTimeAndDate();
	time_t newStartTime = parseDate(previousStartTime, dateString);
	if(!isLaterThan(previousEndTime, newStartTime))
		throw CommonConstant::MESSAGE_INVALID_START_TIME;
	newTask->setStartTimeAndDate(newStartTime);
}
	
void UpdateCommand::updateFloatingEndDate(string dateString)
{
	DeadlineTask* temp;
	temp = new DeadlineTask(previousTask);
	newTask= temp;

	time_t previousEndTime=previousTask->getTimeAndDate();
	time_t newEndTime = parseDate(previousEndTime, dateString);
	newTask->setTimeAndDate(newEndTime);
}

void UpdateCommand::updateDeadlineEndDate(string dateString)
{
	time_t previousEndTime=previousTask->getTimeAndDate();
	time_t newEndTime = parseDate(previousEndTime, dateString);
	newTask->setTimeAndDate(newEndTime);
}
	
void UpdateCommand::updateTimedEndDate(string dateString)
{
	time_t previousStartTime=previousTask->getStartTimeAndDate();
	time_t previousEndTime=previousTask->getEndTimeAndDate();
	time_t newEndTime = parseDate(previousEndTime, dateString);
	
	if(!isLaterThan(newEndTime,previousStartTime))
		throw CommonConstant::MESSAGE_INVALID_END_TIME;
	newTask->setEndTimeAndDate(newEndTime);
}

void UpdateCommand::updateAttribute(string inputSentence)
{
	switch(attributeType)
	{
	case Storage::updateType::UPDATE_TITLE:
		initializePreviousNewTask();
		updateTitle(inputSentence);
		break;

	case Storage::updateType::UPDATE_DESCRIPTION:
		initializePreviousNewTask();
		updateDescription(inputSentence);
		break;

	case Storage::updateType::UPDATE_LOCATION:
		initializePreviousNewTask();
		updateLocation(inputSentence);
		break;

	case Storage::updateType::UPDATE_PERSON:
		initializePreviousNewTask();
		updatePerson(inputSentence);
		break;

	case Storage::updateType::UPDATE_PRIORITY:
		if(isValidIntPriority(inputSentence))
		{
			initializePreviousNewTask();
			updatePriority(stoi(inputSentence,nullptr,CommonConstant::STOI_BASE));
		}
		else if(isValidStringPriority(inputSentence))
		{
			initializePreviousNewTask();
			updatePriority(inputSentence);
		}
		else
			throw CommonConstant::MESSAGE_INVALID_PRIORITY_FORMAT;
		break;

	case Storage::updateType::UPDATE_STATUS:
		if(isValidIntStatus(inputSentence))
		{
			initializePreviousNewTask();
			updateStatus(stoi(inputSentence,nullptr,CommonConstant::STOI_BASE));
		}
		else if(isValidStringStatus(inputSentence))
		{
			initializePreviousNewTask();
			updateStatus(inputSentence);
		}
		else
			throw CommonConstant::MESSAGE_INVALID_STATUS_FORMAT;
		break;

	case Storage::updateType::UPDATE_START_TIME:
		if(isValidTime(inputSentence))
		{
			initializePreviousNewTask();

			switch(determineTaskType(previousTask))
			{
			case floatingTask:
				updateFloatingStartTime(inputSentence);
				break;

			case deadlineTask:
				updateDeadlineStartTime(inputSentence);
				break;

			case timedTask:
				updateTimedStartTime(inputSentence);
				break;
			}
		}
		else
			throw CommonConstant::MESSAGE_INVALID_TIME_FORMAT;
		break;

	case Storage::updateType::UPDATE_END_TIME:
		if(isValidTime(inputSentence))
		{
			initializePreviousNewTask();

			switch(determineTaskType(previousTask))
			{
			case floatingTask:
				updateFloatingEndTime(inputSentence);
				break;
				
			case deadlineTask:
				updateDeadlineEndTime(inputSentence);
				break;

			case timedTask:
				updateTimedEndTime(inputSentence);
				break;
			}
		}
		else
			throw CommonConstant::MESSAGE_INVALID_TIME_FORMAT;
		break;

	case Storage::updateType::UPDATE_START_DATE:
		if(isValidDate(inputSentence))
		{
			initializePreviousNewTask();

			switch(determineTaskType(previousTask))
			{
			case floatingTask:
				updateFloatingStartDate(inputSentence);
				break;

			case deadlineTask:
				updateDeadlineStartDate(inputSentence);
				break;

			case timedTask:
				updateTimedStartDate(inputSentence);
				break;
			}
		}
		else
			throw CommonConstant::MESSAGE_INVALID_TIME_FORMAT;
		break;

	case Storage::updateType::UPDATE_END_DATE:
		if(isValidDate(inputSentence))
		{
			initializePreviousNewTask();

			switch(determineTaskType(previousTask))
			{
			case floatingTask:
				updateFloatingEndDate(inputSentence);
				break;

			case deadlineTask:
				updateDeadlineEndDate(inputSentence);
				break;

			case timedTask:
				updateTimedEndDate(inputSentence);
				break;
			}
		}
		else
			throw CommonConstant::MESSAGE_INVALID_TIME_FORMAT;
		break;
	}
}

void UpdateCommand::removeWhiteSpaces(string& cuurrentString)
{
	size_t p = cuurrentString.find_first_not_of(" ");
	cuurrentString.erase(0, p);
}

void UpdateCommand::checkInput(string& inputSentence)
{
	removeWhiteSpaces(inputSentence);
	if(inputSentence.empty())
		throw CommonConstant::MESSAGE_NO_USER_INPUT_AFTER_COMMAND_UPDATE;
}

void UpdateCommand::checkIndex(string& inputSentence)
{
	stringstream ss(inputSentence);
	string indexString;
	ss >> indexString;
	
	//if index entered is an integer
	if(isValidNumber(indexString))
	{
		index = stoi(inputSentence,nullptr,CommonConstant::STOI_BASE);
	} 
	else 
	{
		throw CommonConstant::MESSAGE_INVALID_INDEX;
	}
	
	//if index entered is within the range
	if(index < CommonConstant::INDEX_ZERO || index>=storage->size())
	{
		throw CommonConstant::MESSAGE_INDEX_OUT_OF_RANGE;
	}

	inputSentence.erase(inputSentence.begin(),inputSentence.begin()+indexString.size());
	removeWhiteSpaces(inputSentence);
}

void UpdateCommand::checkAttributeType(string& inputSentence)
{
	if(inputSentence.empty())
	{
		throw CommonConstant::MESSAGE_INVALID_FORMAT;
	}
	stringstream ss;
	ss.str(inputSentence);
	string attributeString;
	ss >> attributeString;

	attributeType=determineAttributeType(attributeString);

	inputSentence.erase(inputSentence.begin(),inputSentence.begin()+attributeString.size());
	removeWhiteSpaces(inputSentence);
}

void UpdateCommand::checkAttributeValue(string& inputSentence)
{
	if(inputSentence.empty())
	{
		throw CommonConstant::MESSAGE_INVALID_FORMAT;
	}
}

void UpdateCommand::parser(string inputSentence)
{
	checkInput(inputSentence);
	checkIndex(inputSentence);
	checkAttributeType(inputSentence);
	checkAttributeValue(inputSentence);
	updateAttribute(inputSentence);
}